﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using SMA.GENTEv1.Dados;

namespace SMA.GENTEv1
{
    public class FrotaFabricante
    {
        #region Variaveis Membro
        private int _idFrotaFabricante;
        private string _descricao;
        private List<FrotaModelo> _modelo;
        private GENTEEntities _context;
        #endregion

        #region Parametros
        public int IdFrotaFabricante
        {
            get { return _idFrotaFabricante; }
            set { _idFrotaFabricante = value; }
        }

        public string Descricao
        {
            get { return _descricao; }
            set { _descricao = value; }
        }

        public List<FrotaModelo> Modelo
        {
            get { return _modelo; }
            set { _modelo = value; }
        }
        #endregion

        #region Construtores
        public FrotaFabricante()
        {
            _context = new GENTEEntities();
        }

        public FrotaFabricante(int _idfabricante, bool _carregaDados)
        {
            _context = new GENTEEntities();
            if (!_carregaDados)
                this._idFrotaFabricante = _idfabricante;
            else
                Carregar(_idfabricante);
        }
        #endregion

        #region Métodos Privados
        private static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
        {
            if (null == valueSelector)
            {
                throw new
                    ArgumentNullException("valueSelector");
            }
            if (null == values) { throw new ArgumentNullException("values"); }

            ParameterExpression p = valueSelector.Parameters.Single();
            if (!values.Any())
            {
                return e => false;
            }

            var equals = values.Select(value =>
            (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value,
            typeof(TValue))));
            var body = equals.Aggregate<Expression>((accumulate, equal) =>
            Expression.Or(accumulate, equal));
            return Expression.Lambda<Func<TElement, bool>>(body, p);
        }

        private void Carregar(int _idfabricante)
        {
            try
            {
                var consulta = (from fabricante in _context.tab_frota_fabricante
                                where fabricante.id_frota_fabricante == _idfabricante
                                select fabricante);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    this._idFrotaFabricante = list.id_frota_fabricante;
                    this._descricao = list.descricao;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private bool VerificaCadastro()
        {
            try
            {
                bool verifica = false;

                if (this._descricao == string.Empty)
                    throw new Exception("É necessário informar o nome do fabricante!");

                if (this._idFrotaFabricante == 0)
                {
                    var consulta = (from fabricante in _context.tab_frota_fabricante
                                    where fabricante.descricao == this._descricao
                                    select fabricante);

                    if (consulta.ToList().Count > 0)
                        throw new Exception("Já existe um fabricante com este nome. Operação cancelada!");
                }

                verifica = true;
                return verifica;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos Públicos

        #region Métodos de Seleção
        public List<FrotaFabricante> SelectAll()
        {
            try
            {
                List<FrotaFabricante> listFabricantes = new List<FrotaFabricante>();

                var consulta = (from fabricante in _context.tab_frota_fabricante
                                select fabricante);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    FrotaFabricante fabricante = new FrotaFabricante();
                    fabricante.IdFrotaFabricante = list.id_frota_fabricante;
                    fabricante.Descricao = list.descricao;

                    listFabricantes.Add(fabricante);
                }

                return listFabricantes;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<FrotaFabricante> SelectPor(int[] _idfabricante)
        {
            try
            {
                List<FrotaFabricante> listFabricante = new List<FrotaFabricante>();

                var consulta = (from fabricante in _context.tab_frota_fabricante.Where((BuildContainsExpression<tab_frota_fabricante, int>(item => item.id_frota_fabricante, _idfabricante)))
                                select fabricante);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    FrotaFabricante fabricante = new FrotaFabricante();
                    fabricante.IdFrotaFabricante = list.id_frota_fabricante;
                    fabricante.Descricao = list.descricao;

                    listFabricante.Add(fabricante);
                }

                return listFabricante;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<FrotaFabricante> SelectPor(string _descricao)
        {
            try
            {
                List<FrotaFabricante> listFabricante = new List<FrotaFabricante>();

                var consulta = (from fabricante in _context.tab_frota_fabricante
                                where ((_descricao != "") ? fabricante.descricao.StartsWith(_descricao) : (1 == 1))
                                select fabricante);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    FrotaFabricante fabricante = new FrotaFabricante();
                    fabricante.IdFrotaFabricante = list.id_frota_fabricante;
                    fabricante.Descricao = list.descricao;

                    listFabricante.Add(fabricante);
                }

                return listFabricante;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region Métodos de Persistência
        public void Salvar()
        {
            try
            {
                if (VerificaCadastro())
                {
                    if (this._idFrotaFabricante == 0)
                    {
                        tab_frota_fabricante tabFabricante = new tab_frota_fabricante();
                        tabFabricante.descricao = this._descricao;

                        _context.AddTotab_frota_fabricante(tabFabricante);
                        _context.SaveChanges();
                    }
                    else
                    {
                        tab_frota_fabricante tabFabricante = (from fabricante in _context.tab_frota_fabricante
                                                              where fabricante.id_frota_fabricante == this._idFrotaFabricante
                                                              select fabricante).First();

                        tabFabricante.descricao = this._descricao;

                        _context.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public void Excluir()
        {
            try
            {
                FrotaModelo modelo = new FrotaModelo();
                this._modelo = modelo.SelectModelos(this._idFrotaFabricante);

                if (this._modelo.Count > 0)
                    throw new Exception("Existe(m) modelo(s) vinculados para este fabricante, desta forma, não pode ser feito a exclusão. Operação cancelada!");

                var consulta = (from fabricante in _context.tab_frota_fabricante
                                where fabricante.id_frota_fabricante == this._idFrotaFabricante
                                select fabricante);

                var listConsulta = consulta.ToList();

                foreach (var list in listConsulta)
                {
                    _context.DeleteObject(list);
                    _context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #endregion
    }
}
